﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ndo.Maths
{
    public class GaussianRandom
    {
        private int iset = 0;
        private double gset;
        private Random r1, r2;

        public GaussianRandom()
        {
            int tick = Environment.TickCount;
            r1 = new Random(tick);
            r2 = new Random(~tick);
        }
        public GaussianRandom(Random r)
            : this(r, r)
        { }

        public GaussianRandom(Random r1, Random r2)
        {
            this.r1 = r1;
            this.r2 = r2;
        }
        public const double Shrink = 4.6566128752457969E-10;

        public double NextDouble()
        {
            double fac, rsq, v1, v2;
            if (iset == 0)
            {
                do
                {
                    v1 = 2.0 * Shrink * this.r1.Next() - 1.0;
                    v2 = 2.0 * Shrink * this.r2.Next() - 1.0;
                    rsq = v1 * v1 + v2 * v2;
                } while (rsq >= 1.0 || rsq == 0.0);

                fac = Math.Sqrt(-2.0 * Math.Log(rsq) / rsq);
                gset = v1 * fac;
                iset = 1;
                return v2 * fac;
            }
            else
            {
                iset = 0;
                return gset;
            }
        }
    }
}
